package com.haohan.cloud.scm.common.tools.handler;

import cn.hutool.core.util.StrUtil;
import com.haohan.cloud.scm.common.tools.exception.EmptyDataException;
import com.haohan.cloud.scm.common.tools.exception.ErrorDataException;
import com.haohan.cloud.scm.common.tools.util.RUtil;
import com.pig4cloud.pigx.common.core.util.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.NestedRuntimeException;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.stereotype.Component;
import org.springframework.validation.BindException;
import org.springframework.validation.ObjectError;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.util.List;

/**
 * 异常处理
 *
 * @author dy
 * @date 2019/5/16
 */
@RestControllerAdvice
@Slf4j
@Component
public class BusinessExceptionHandler {

    /**
     * 全局异常
     *
     * @param e
     * @return
     */
    @ExceptionHandler(Exception.class)
    public R handleException(Exception e) {
        log.debug("============ExceptionHandler=========== {}", e.getMessage());
        e.printStackTrace();
        return RUtil.error("服务异常");
    }

    /**
     * 权限不足异常
     *
     * @param e
     * @return
     */
    @ExceptionHandler(AccessDeniedException.class)
    public R handleAccessDeniedException(AccessDeniedException e) {
        log.debug("============AccessDeniedException=========== {}", e.getMessage());
        return RUtil.error("权限不足,不允许访问");
    }

    /**
     * 请求方法错误
     *
     * @param e
     * @return
     */
    @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
    public R handleHttpRequestException(HttpRequestMethodNotSupportedException e) {
        log.debug("============HttpRequestMethodNotSupportedException=========== {}", e.getMessage());
        return RUtil.error(StrUtil.isEmpty(e.getMessage()) ? "数据错误" : "请求方法有误：" + e.getMessage());
    }

    /**
     * 请求数据绑定错误
     *
     * @param e
     * @return
     */
    @ExceptionHandler(HttpMessageNotReadableException.class)
    public R handleHttpException(HttpMessageNotReadableException e) {
        log.debug("============HttpMessageNotReadableException=========== {}", e.getMessage());
        return RUtil.error(StrUtil.isEmpty(e.getMessage()) ? "数据错误" : "请求参数有误：" + e.getMessage());
    }

    /**
     * 参数校验
     *
     * @param ex
     * @return
     */
    @ExceptionHandler(BindException.class)
    public R handleBindException(BindException ex) {
        log.debug("============BindExceptionHandler===========");
        StringBuilder sb = new StringBuilder();
        sb.append("传参有误:");
        List<ObjectError> errors = ex.getAllErrors();
        for (ObjectError error : errors) {
            sb.append(error.getDefaultMessage()).append(";");
        }
        log.debug("{} ============BindExceptionHandler===========", sb.toString());
        return RUtil.error(sb.toString());
    }

    /**
     * 参数校验
     *
     * @param ex
     * @return
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public R handleBindException(MethodArgumentNotValidException ex) {
        log.debug("============MethodArgumentNotValidException===========");
        StringBuilder sb = new StringBuilder();
        sb.append("传参有误:");
        List<ObjectError> errors = ex.getBindingResult().getAllErrors();
        for (ObjectError error : errors) {
            sb.append(error.getDefaultMessage()).append(";");
        }
        log.debug("{} ============MethodArgumentNotValidException===========", sb.toString());
        return RUtil.error(sb.toString());
    }

    /**
     * 数据为空时
     *
     * @param dx
     * @return
     */
    @ExceptionHandler(EmptyDataException.class)
    public R handleException(EmptyDataException dx) {
        log.debug("============EmptyDataExceptionHandler=========== {}", dx.getMessage());
        return RUtil.error(StrUtil.isEmpty(dx.getMessage()) ? "数据为空" : dx.getMessage());
    }

    /**
     * 数据错误时
     *
     * @param dx
     * @return
     */
    @ExceptionHandler(ErrorDataException.class)
    public R handleException(ErrorDataException dx) {
        log.debug("============ErrorDataExceptionHandler=========== {}", dx.getMessage());
        return RUtil.error(StrUtil.isEmpty(dx.getMessage()) ? "数据错误" : dx.getMessage());
    }

    /**
     * 数据查询错误
     *
     * @param bx
     * @return
     */
    @ExceptionHandler(NestedRuntimeException.class)
    public R handleException(NestedRuntimeException bx) {
        log.debug("============NestedRuntimeExceptionHandler=========== {}", bx.getMessage());
        bx.printStackTrace();
        return RUtil.error(StrUtil.isEmpty(bx.getMessage()) ? "数据查询错误" : "数据查询错误：" + bx.getMessage());
    }

}
